/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spotkanie;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author mateusz.ledzewicz
 */
public class CrossObject extends Thread{
    
    public static final int in = 0;
    public static final int out = 1;
    public ArrayList<CarThread> cars;
    public int count = 0;
    public boolean free = true;
    private PrintWriter outWriter = null; 
    
    
    private final Lock lock = new ReentrantLock();

    private final Condition isFree = lock.newCondition();
    
    
    public CrossObject(int numbersOfCars){
        cars = new ArrayList();
        Random rnd = new Random();
        try {
            outWriter = new PrintWriter("Raport.csv");
        } catch (FileNotFoundException ex) {
            Logger.getLogger(CrossObject.class.getName()).log(Level.SEVERE, null, ex);
        }
        for(int i=0;i<numbersOfCars;i++){
            CarThread car = new CarThread(rnd.nextInt(1000), this, outWriter);
            cars.add(car);
            car.start();
        }
    }
        
    public void select(CarThread car, int param){
        
        try{
            if(param == in){
                this.driveIn(car);
            } else if(param == out && free == false && car.isOnCross()){
                this.driveOut(car);
            }
        }catch(InterruptedException ex){
              Logger.getLogger(Policeman.class.getName()).log(Level.SEVERE, null, ex);
        } catch(Exception ex){
             Logger.getLogger(Policeman.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
     private void driveIn(CarThread car) throws InterruptedException {
        lock.lock();

        try {
            
            while (free == false) {
                //car.log("Wait");
                isFree.await();
            }
               
            free = false;
            car.move();
        } finally {
            lock.unlock();
        }
    }
     
      private void driveOut(CarThread car) throws Exception {
        lock.lock();
        int numbersOfCars = 0;
        for (CarThread c : this.cars){
            if(c.isOnCross()){
                numbersOfCars++;
            }
        }
        if(numbersOfCars > 1)
            throw new Exception("Colision "+ numbersOfCars);
        
        try {
            car.move();
            free = true;
            isFree.signal();
        } finally {
            lock.unlock();
        }
    }
    
    
    
    public ArrayList<CarThread> getCars(){
        return this.cars;
    }
}
